*! nsplit 2.0 Dan Blanchette 02Dec2004
* serious suggestions by NJC implemented
*! nsplit 1.1 Dan Blanchette 30Nov2004
*- only allow one variable to be processed at a time
*! the carolina population center, unc-ch
program nsplit, rclass 
	version 8
	syntax varname(numeric) [if] [in], ///
	Digits(numlist int >0) [Generate(string)]

	quietly { 
		// any to use 
		marksample touse 
		count if `touse' 
		if r(N) == 0 error 2000 

		// checks for negative values and non-integers 
		cap assert `varlist' >= 0 if `touse' 
		if _rc { 
			di as err "variable `varlist' contains negative values"
			exit 411 
		} 	
		cap assert `varlist' == int(`varlist') if `touse' 
		if _rc { 
			di as err "variable `varlist' contains fractional values"
			exit 459 
		} 	

		su `varlist' if `touse', meanonly 
		if length("`r(min)'") != length("`r(max)'") { 
			noi di "{txt}note: values of {res}`varlist' {txt}vary in length" 
		} 	

		local len = length("`r(max)'")
				
		if `len' > 7  & "`: type `varlist''" == "float" {
			noi di "{p}{txt}note: variable {res}`varlist' {txt}is of numeric storage type {res}float {txt} " ///
                                "and contains more digits than can be accurately stored in this {help datatype}{p_end}"
			noi di as txt "{p}check all values generated by {help nsplit}{p_end}" 
		}
		if `len' > 16  & "`: type `varlist''" == "double" {
			noi di "{p}{txt}note: variable {res}`varlist' {txt}contains "  ///
				"more digits than can be accurately stored{p_end}"
			noi di as txt "{p}check all values generated by {help nsplit}{p_end}" 
		}

		local nv : word count `digits'
		if `nv' == 1  {  // need to create pattern
			local nv = `len'/`digits' 
			if mod(`nv',1) { 
				di as err "maximum length `len' of `varlist' " ///
				"is not divisible by `digits'" 
				exit 459 
			} 	
			local digits : di _dup(`nv') "`digits' "
		}

		foreach d of local digits {
			local dsum = `dsum' + `d' 
		}
		
		if `dsum' != `len' {
                        di as err "{p}The pattern `digits' is not a valid pattern " ///
				  "for variable `varlist'.{p_end}"
			exit 459 
                }

		if "`generate'" != "" {
			local ng : word count `generate' 
			if `ng' > 1 & `ng' > `nv' { 
				noi di "{p}{err}the `ng' variables in {res}`generate' " ///
				"{err}exceeds `nv' variables implied by `digits'{p_end}" 
				exit 498 
			} 	
			else if `ng' > 1 & `ng' < `nv' { 
				noi di "{p}{txt}note: the `ng' variables " ///
				"{res}`generate' {txt}are fewer than `nv' variables " ///
				"implied by `digits'{p_end}" 
				di as err "too few variables specified"
				exit 102
			} 	
			else if `ng' == 1 & `nv' > `ng' { 
				forval i = 1/`nv' { 
					local g "`g' `generate'`i'" 
				}
				local generate "`g'" 
			}
		}
		else {   
			forval i = 1/`nv' {
				local generate "`generate' `varlist'`i'"
			}
		}

		capture confirm new var `generate' 
		if _rc { 
			di as err "new variable list `generate' invalid"
			exit _rc 
		} 	

		local ten = 10^`len'
		local j = 1
		foreach i of local digits {
			local nvar : word `j' of `generate'
			local sten = `ten'/(10^`i')
			if  inrange(`i',0,2)   local type "byte"
			else if  inrange(`i',3,4) local type "int"
			else if  inrange(`i',5,9) local type "long"
			else  {
				local type "double"
				if `i' > 16  noi di "{p}{txt}note: new variable {res}`nvar' {txt}contains "  ///
							"more digits than can be accurately stored{p_end}"
			}
			di `" {res}gen `type' `nvar' = int(mod(`varlist',`ten')/`sten') `if' `in'"'
				   gen `type' `nvar' = int(mod(`varlist',`ten')/`sten') `if' `in'
			label var `nvar' `"Part `j' of `varlist' "'
			local ten = `ten'/10^`i'
			local ++j
		}
	}	

	return local varlist "`generate'" 
end

